package com.cskaoyan.service;

import com.cskaoyan.bean.param.WxBaseParam;
import com.cskaoyan.bean.param.WxMyCouponListParam;
import com.cskaoyan.bean.pojo.MallCoupon;
import com.cskaoyan.bean.pojo.MallCouponExample;
import com.cskaoyan.bean.pojo.MallCouponUser;
import com.cskaoyan.bean.pojo.MallCouponUserExample;
import com.cskaoyan.bean.wxvo.WxCouponListVo;
import com.cskaoyan.bean.wxvo.WxCouponReceiveVo;
import com.cskaoyan.bean.wxvo.WxCouponVo;
import com.cskaoyan.mapper.MallCouponMapper;
import com.cskaoyan.mapper.MallCouponUserMapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

@Transactional(rollbackFor = Exception.class)
@Service
public class WxCouponServiceImpl implements WxCouponService {
    /**
     * 优惠券状态，
     * 如果是0则是正常可用；
     * 如果是1则是已使用;
     * 如果是2则是过期。
     */

    @Autowired
    MallCouponMapper mallCouponMapper;

    @Autowired
    MallCouponUserMapper mallCouponUserMapper;

    @Override
    public WxCouponListVo couponList(WxBaseParam param) {
        PageHelper.startPage (param.getPage (), param.getSize ());
        WxCouponVo wxCouponVo = new WxCouponVo ();
        ArrayList<WxCouponVo> wxCouponVoList = new ArrayList<> ();

        MallCouponExample mallCouponExample = new MallCouponExample ();
        MallCouponExample.Criteria criteria = mallCouponExample.createCriteria ();
        //查询可用优惠劵
        criteria.andDeletedEqualTo (false);
        criteria.andStatusEqualTo ((short) 0);
        List<MallCoupon> mallCoupons = mallCouponMapper.selectByExample (mallCouponExample);

        for (MallCoupon mallCoupon : mallCoupons) {
            //判断是否过期,过期不显示
            if (isOverDate (mallCoupon)) {
                mallCoupon.setStatus ((short) 2);
                mallCouponMapper.updateByPrimaryKeySelective (mallCoupon);
                continue;
            }
            wxCouponVo.setId (mallCoupon.getId ())
                    .setName (mallCoupon.getName ())
                    .setDesc (mallCoupon.getDesc ())
                    .setTag (mallCoupon.getTag ())
                    .setDiscount (mallCoupon.getDiscount ())
                    .setMin (mallCoupon.getMin ())
                    .setDays (mallCoupon.getDays ())
                    .setStartTime (mallCoupon.getStartTime ())
                    .setEndTime (mallCoupon.getEndTime ());
            wxCouponVoList.add (wxCouponVo);
        }

        PageInfo<WxCouponVo> wxCouponVoPageInfo = new PageInfo<> (wxCouponVoList);
        WxCouponListVo wxCouponListVo = new WxCouponListVo ();
        wxCouponListVo.setData (wxCouponVoList);
        wxCouponListVo.setCount ((int) wxCouponVoPageInfo.getTotal ());
        return wxCouponListVo;
    }

    @Override
    public WxCouponListVo myList(WxMyCouponListParam param, Integer userId) {

        PageHelper.startPage (param.getPage (), param.getSize ());

        MallCouponUserExample mallCouponUserExample = new MallCouponUserExample ();
        MallCouponUserExample.Criteria criteria = mallCouponUserExample.createCriteria ();
        //根据userId和状态码查询优惠劵
        criteria.andDeletedEqualTo (false);
        criteria.andUserIdEqualTo (userId);
        criteria.andStatusEqualTo (param.getStatus ());
        List<MallCouponUser> mallCouponUsers = mallCouponUserMapper.selectByExample (mallCouponUserExample);

        WxCouponListVo wxCouponListVo = new WxCouponListVo ();
        ArrayList<WxCouponVo> CouponVoList = new ArrayList<> ();
        WxCouponVo wxCouponVo = new WxCouponVo ();


        for (MallCouponUser mallCouponUser : mallCouponUsers) {

            MallCoupon mallCoupon = mallCouponMapper.selectByPrimaryKey (mallCouponUser.getCouponId ());
            wxCouponVo.setId (mallCoupon.getId ())
                    .setName (mallCoupon.getName ())
                    .setDesc (mallCoupon.getDesc ())
                    .setTag (mallCoupon.getTag ())
                    .setDiscount (mallCoupon.getDiscount ())
                    .setMin (mallCoupon.getMin ())
                    .setDays (mallCoupon.getDays ())
                    .setStartTime (mallCoupon.getStartTime ())
                    .setEndTime (mallCoupon.getEndTime ());
            CouponVoList.add (wxCouponVo);
        }
        PageInfo<WxCouponVo> wxCouponVoPageInfo = new PageInfo<> (CouponVoList);
        long total = wxCouponVoPageInfo.getTotal ();
        wxCouponListVo.setCount ((int) total);
        wxCouponListVo.setData (CouponVoList);

        return wxCouponListVo;
    }

    @Override
    public List<WxCouponVo> selectList(Integer userId) {
        MallCouponUserExample mallCouponUserExample = new MallCouponUserExample ();
        MallCouponUserExample.Criteria criteria = mallCouponUserExample.createCriteria ();
        criteria.andDeletedEqualTo (false);
        criteria.andUserIdEqualTo (userId);
        criteria.andStatusEqualTo ((short) 0);
        List<MallCouponUser> mallCouponUsers = mallCouponUserMapper.selectByExample (mallCouponUserExample);
        ArrayList<WxCouponVo> couponVoList = new ArrayList<> ();
        for (MallCouponUser mallCouponUser : mallCouponUsers) {
            MallCoupon mallCoupon = mallCouponMapper.selectByPrimaryKey (mallCouponUser.getCouponId ());
            //判断优惠劵是否过期
            if (isOverDate (mallCoupon)) {
                mallCoupon.setStatus ((short) 2);
                mallCouponMapper.updateByPrimaryKeySelective (mallCoupon);
                continue;
            }
            WxCouponVo wxCouponVo = new WxCouponVo ();

            wxCouponVo.setId (mallCoupon.getId ())
                    .setName (mallCoupon.getName ())
                    .setDesc (mallCoupon.getDesc ())
                    .setTag (mallCoupon.getTag ())
                    .setDiscount (mallCoupon.getDiscount ())
                    .setMin (mallCoupon.getMin ())
                    .setDays (mallCoupon.getDays ())
                    .setStartTime (mallCoupon.getStartTime ())
                    .setEndTime (mallCoupon.getEndTime ());
            couponVoList.add (wxCouponVo);
        }

        return couponVoList;
    }

    @Override
    public WxCouponReceiveVo receiveCoupon(Integer couponId, Integer userId) {
        MallCoupon mallCoupon = mallCouponMapper.selectByPrimaryKey (couponId);
        if (ObjectUtils.isEmpty (mallCoupon)){
            return WxCouponReceiveVo.fail ();
        }
        //优惠劵参数检验
        if(couponDataCheck (mallCoupon)){
            return WxCouponReceiveVo.couponDataFalse ();
        }
        //判断优惠劵是否过期
        if (isOverDate (mallCoupon)) {
            mallCoupon.setStatus ((short) 2);
            mallCouponMapper.updateByPrimaryKeySelective (mallCoupon);
            return WxCouponReceiveVo.overDate ();
        }
        if (mallCoupon.getDeleted () == true) {
            return WxCouponReceiveVo.fail ();
        }
        if (mallCoupon.getStatus () == (short) 1 || mallCoupon.getStatus () == (short) 2) {
            return WxCouponReceiveVo.fail ();
        }
        MallCouponUserExample mallCouponUserExample = new MallCouponUserExample ();
        MallCouponUserExample.Criteria criteria = mallCouponUserExample.createCriteria ();
        criteria.andDeletedEqualTo (false);
        criteria.andUserIdEqualTo (userId);
        criteria.andCouponIdEqualTo (couponId);
        List<MallCouponUser> mallCouponUsers = mallCouponUserMapper.selectByExample (mallCouponUserExample);
        MallCouponUser mallCouponUser = new MallCouponUser ();
        int size = mallCouponUsers.size ();
        Date date = new Date ();
        if ((short) size >= mallCoupon.getLimit ()) {
            return WxCouponReceiveVo.have ();
        }
        if (size == 0 || (short) size < mallCoupon.getLimit ()) {
            int timeType = mallCoupon.getTimeType ();
            int days = mallCoupon.getDays ();
            mallCouponUser.setUserId (userId)
                    .setCouponId (couponId)
                    .setStatus (mallCoupon.getStatus ())
                    .setStartTime (date)
                    .setAddTime (date)
                    .setUpdateTime (date)
                    .setDeleted (false);
            if (timeType == 0) {
                mallCouponUser.setEndTime (addDayOfDate (date, days));
            }
            if (timeType == 1) {
                mallCouponUser.setEndTime (mallCoupon.getEndTime ());
            }
            mallCouponUserMapper.insertSelective (mallCouponUser);
            return WxCouponReceiveVo.ok ();
        }

        return WxCouponReceiveVo.fail ();
    }

    @Override
    public WxCouponReceiveVo exchangeCoupon(String code, Integer userId) {
        MallCouponExample mallCouponExample = new MallCouponExample ();
        MallCouponExample.Criteria criteria = mallCouponExample.createCriteria ();
        criteria.andDeletedEqualTo (false);
        criteria.andCodeEqualTo (code);
        criteria.andStatusEqualTo ((short) 0);
        List<MallCoupon> mallCoupons = mallCouponMapper.selectByExample (mallCouponExample);
        int size = mallCoupons.size ();
        if (size == 0) {
            return WxCouponReceiveVo.codeFalse ();
        }
        if (size == 1) {
            MallCoupon mallCoupon = mallCoupons.get (0);
            //优惠劵参数检验
            if(couponDataCheck (mallCoupon)){
                return WxCouponReceiveVo.couponDataFalse ();
            }
            //判断优惠劵是否过期
            if (isOverDate (mallCoupon)) {
                mallCoupon.setStatus ((short) 2);
                mallCouponMapper.updateByPrimaryKeySelective (mallCoupon);
                return WxCouponReceiveVo.overDate ();
            }
            int limit = mallCoupon.getLimit ();
            MallCouponUserExample mallCouponUserExample = new MallCouponUserExample ();
            MallCouponUserExample.Criteria criteria1 = mallCouponUserExample.createCriteria ();
            criteria1.andCouponIdEqualTo (mallCoupon.getId ());
            criteria1.andUserIdEqualTo (userId);
            List<MallCouponUser> mallCouponUsers = mallCouponUserMapper.selectByExample (mallCouponUserExample);
            MallCouponUser mallCouponUser = new MallCouponUser ();

            if (limit < mallCouponUsers.size () || limit == 0) {
                Date date = new Date ();
                int days = mallCoupon.getDays ();
                int timeType = mallCoupon.getTimeType ();
                mallCouponUser.setUserId (userId)
                        .setCouponId (mallCoupon.getId ())
                        .setStatus (mallCoupon.getStatus ())
                        .setStartTime (date)
                        .setAddTime (date)
                        .setUpdateTime (date)
                        .setDeleted (false);
                if (timeType == 0) {
                    mallCouponUser.setEndTime (addDayOfDate (date, days));
                }
                if (timeType == 1) {
                    mallCouponUser.setEndTime (mallCoupon.getEndTime ());
                }
                mallCouponUserMapper.insertSelective (mallCouponUser);
                return WxCouponReceiveVo.ok ();
            }
            return WxCouponReceiveVo.have ();
        }
        return WxCouponReceiveVo.fail ();

    }

    /**
     * 判断优惠劵是否过期
     *
     * @param mallCoupon
     * @return
     */
    private static boolean isOverDate(MallCoupon mallCoupon) {
        Date date = new Date ();
        int timeType = mallCoupon.getTimeType ();
        if (timeType == 0) {
            return false;
        }
        if (timeType == 1) {

            if (mallCoupon.getEndTime ().after (date)) {
                return false;
            }
            return true;
        }
        return true;
    }

    /**
     * 增加天数
     *
     * @param date
     * @param i
     * @return
     */
    private static Date addDayOfDate(Date date, int i) {
        Calendar c = Calendar.getInstance ();
        c.setTime (date);
        c.add (Calendar.DATE, i);
        Date newDate = c.getTime ();
        return newDate;
    }

    /**
     * 优惠劵数据检查
     * @param mallCoupon
     * @return
     */
    private static boolean couponDataCheck(MallCoupon mallCoupon){
        if(ObjectUtils.isEmpty (mallCoupon.getTimeType ())||ObjectUtils.isEmpty (mallCoupon.getStatus ())||ObjectUtils.isEmpty (mallCoupon.getLimit ())){
            return true;
        }
        return false;
    }
}
